package com.linkhub.oms.admin.modules.wms.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.linkhub.oms.admin.modules.wms.service.WmsDeliveryConfirmFulfillmentService;
import com.linkhub.oms.common.enums.mp.*;
import com.linkhub.oms.dao.mpservice.*;
import com.linkhub.oms.data.sync.api.shopify.domain.request.FulfillmentRequest;
import com.linkhub.oms.data.sync.api.shopify.domain.response.FulfillmentOrderResponse;
import com.linkhub.oms.data.sync.api.shopify.domain.response.FulfillmentResponse;
import com.linkhub.oms.data.sync.api.yunexpress.domain.request.GetTrackingNumberRequest;
import com.linkhub.oms.data.sync.api.yunexpress.domain.response.GetTrackingNumberResponse;
import com.linkhub.oms.data.sync.service.OMSYunExpressApiService;
import com.linkhub.oms.data.sync.service.ShopifyApiService;
import com.linkhub.oms.entity.OrderEntity;
import com.linkhub.oms.entity.OrderProductEntity;
import com.linkhub.oms.entity.ShopEntity;
import com.linkhub.oms.entity.ThirdPartyLogisticsUrlEntity;
import lombok.extern.slf4j.Slf4j;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.linkhub.oms.common.constant.ProjectConstant.ASYNC_EXECUTOR;
import static com.linkhub.oms.common.constant.ShopifyConstant.*;
import static com.linkhub.oms.common.constant.ShopifyConstant.TRACK_NUMBER;

/**
 * @author Jaycle
 * @version 1.0.0
 * @Description shopify 发货服务类
 * @createTime 2024/07/13 17:22
 */
@Slf4j
@Service
public class WmsDeliveryConfirmFulfillmentServiceImpl implements WmsDeliveryConfirmFulfillmentService {

    @Resource
    private OMSYunExpressApiService omsYunExpressApiService;
    @Resource
    private ShopifyApiService shopifyApiService;
    @Resource
    private IThirdPartyLogisticsUrlService thirdPartyLogisticsUrlService;
    @Resource
    private IShopService shopService;
    @Resource
    private IOrderService orderService;
    @Resource
    private IOrderProductService orderProductService;
    @Resource
    private IShopProductSkuMappingService shopProductSkuMappingService;

    @Override
    @Async(ASYNC_EXECUTOR)
    @Transactional(rollbackFor = Exception.class)
    public void runShopifyShipping( OrderEntity orderEntity ) {
        // 如果是拆分订单，检查当前订单是否最后一个确认出库的子订单，如果是则直接全部发货;如果不是拆分订单，直接全部发货
        boolean isLastFulfillmentSubOrder = orderService.isLastFulfillmentSubOrder(orderEntity);

        if (isLastFulfillmentSubOrder) {
            // 并发处理发货
            runShopifyShippingAsync(orderEntity);
        } else {
            // 同步串行处理发货，避免并发问题
            runShopifyShippingSync(orderEntity);
        }
    }

    @Async(ASYNC_EXECUTOR)
    @Transactional(rollbackFor = Exception.class)
    public void runShopifyShippingAsync( OrderEntity orderEntity ) {
        fulfillmentOrder(true, orderEntity);
    }

    @Transactional(rollbackFor = Exception.class)
    public synchronized void runShopifyShippingSync( OrderEntity orderEntity ) {
        fulfillmentOrder(false, orderEntity);
    }

    private void fulfillmentOrder( boolean isLastFulfillmentSubOrder, OrderEntity orderEntity ) {
        if (!isLastFulfillmentSubOrder) {
            // 获取拆分订单最新状态
            isLastFulfillmentSubOrder = orderService.isLastFulfillmentSubOrder(orderEntity);
        }
        String sysShopId = orderEntity.getSysShopId();
        String sysOrderId = orderEntity.getSysOrderId();
        Long platFormOrderId = orderEntity.getPlatFormOrderId();

        // 获取Shopify订单发货信息
        ShopEntity shopEntity = shopService.getByShopId(sysShopId);
        if (shopEntity != null) {
            String url = shopEntity.getUrl();
            String accessToken = shopEntity.getAccessToken();
            FulfillmentOrderResponse fulfillmentOrderResponse = shopifyApiService.fulfillmentOrders(url, accessToken, String.valueOf(platFormOrderId));
            List<FulfillmentOrderResponse.LineItem> allValidFulfillment = fulfillmentOrderResponse.getAllValidFulfillment();

            FulfillmentRequest fulfillmentRequest = new FulfillmentRequest();
            FulfillmentRequest.Fulfillment fulfillment = new FulfillmentRequest.Fulfillment();
            FulfillmentRequest.TrackingInfo trackingInfo = new FulfillmentRequest.TrackingInfo();
            trackingInfo.setCompany(TRACKING_INFO_COMPANY);

            List<FulfillmentRequest.LineItemsByFulfillmentOrder> lineItemsByFulfillmentOrderList = new ArrayList<>();

            //设置物流追踪链接并设置追踪号
            setLogisticUrlAndSetNumber(orderEntity, trackingInfo);

            if (isLastFulfillmentSubOrder) {
                // 如果不是拆分订单或已经是拆分订单最后一个订单，则直接全部发货
                List<Long> uniqueFulfillmentOrderIds = allValidFulfillment.stream()
                        .map(FulfillmentOrderResponse.LineItem::getFulfillmentOrderId)
                        .distinct()
                        .collect(Collectors.toList());
                for (Long uniqueFulfillmentOrderId : uniqueFulfillmentOrderIds) {
                    FulfillmentRequest.LineItemsByFulfillmentOrder lineItemsByFulfillmentOrder = new FulfillmentRequest.LineItemsByFulfillmentOrder();
                    lineItemsByFulfillmentOrder.setFulfillmentOrderId(uniqueFulfillmentOrderId);
                    lineItemsByFulfillmentOrderList.add(lineItemsByFulfillmentOrder);
                }
            } else {
                // 拆分订单按照订单里面的商品个数发货
                // 获取订单商品对应的shopify商品ID
                Map<Long, Integer> orderProductEntitiesMap = getOrderProductEntitiesMap(sysOrderId);
                for (FulfillmentOrderResponse.LineItem lineItem : allValidFulfillment) {
                    long id = lineItem.getId();
                    long fulfillmentOrderId = lineItem.getFulfillmentOrderId();
                    long variantId = lineItem.getVariantId();
                    int fulfillableQuantity = lineItem.getFulfillableQuantity();

                    if (orderProductEntitiesMap.containsKey(variantId)) {
                        Integer currentQuantity = orderProductEntitiesMap.get(variantId);
                        if (currentQuantity > 0) {
                            FulfillmentRequest.LineItemsByFulfillmentOrder lineItemsByFulfillmentOrder = new FulfillmentRequest.LineItemsByFulfillmentOrder();
                            lineItemsByFulfillmentOrder.setFulfillmentOrderId(fulfillmentOrderId);
                            FulfillmentRequest.FulfillmentOrderLineItem fulfillmentOrderLineItem = new FulfillmentRequest.FulfillmentOrderLineItem();
                            fulfillmentOrderLineItem.setId(id);
                            // 取出两个值的最小值
                            int minimumQuantity = Math.min(currentQuantity, fulfillableQuantity);
                            fulfillmentOrderLineItem.setQuantity(minimumQuantity);
                            lineItemsByFulfillmentOrder.setFulfillmentOrderLineItems(Lists.newArrayList(fulfillmentOrderLineItem));
                            lineItemsByFulfillmentOrderList.add(lineItemsByFulfillmentOrder);

                            orderProductEntitiesMap.put(variantId, currentQuantity - minimumQuantity);
                        }
                    }
                }
//                if (CollUtil.isEmpty(lineItemsByFulfillmentOrderList)) {
//                    // m没找到
//                    OrderEntity update = new OrderEntity();
//                    update.setShopifyFulfillmentFlag(BoolEnum.YES);
//                    orderService.updateOrderInfo(sysOrderId, update);
//                }
            }
            fulfillment.setTrackingInfo(trackingInfo);
            fulfillment.setLineItemsByFulfillmentOrder(lineItemsByFulfillmentOrderList);
            fulfillmentRequest.setFulfillment(fulfillment);
            FulfillmentResponse fulfillmentsRespone = shopifyApiService.fulfillments(url, accessToken, fulfillmentRequest);
            if (fulfillmentsRespone.success()) {
                // 发货成功，更改订单shopify发货状态
                OrderEntity update = new OrderEntity();
                update.setShopifyFulfillmentFlag(BoolEnum.YES);
                orderService.updateOrderInfo(sysOrderId, update);
            }
        }
    }

    private Map<Long, Integer> getOrderProductEntitiesMap( String sysOrderId ) {
        List<OrderProductEntity> orderProductEntities = orderProductService.listBySysOrderId(sysOrderId);
        orderProductEntities.stream()
                .filter(entity -> entity.getShopSkuId() == null)
                .forEach(entity -> entity.setShopSkuId(shopProductSkuMappingService.getBySkuId(entity.getSkuId()).getShopSkuId()));

        // 过滤掉 shopSkuId 仍然为空的对象并转换为 Map
        return orderProductEntities.stream()
                .filter(entity -> entity.getShopSkuId() != null)
                .collect(Collectors.toMap(
                        OrderProductEntity::getShopSkuId,
                        OrderProductEntity::getCurrentQuantity
                ));
    }

    private void setLogisticUrlAndSetNumber( OrderEntity orderEntity, FulfillmentRequest.TrackingInfo trackingInfo ) {
        ThirdPartyLogisticsUrlEntity thirdPartyLogisticsUrlEntity = thirdPartyLogisticsUrlService.queryById(orderEntity.getSysShopId());
        // 同步到shopify物流追踪链接
        String logisticUrl;
        String number;
        if (Objects.isNull(thirdPartyLogisticsUrlEntity)) {
            // 没设置物流追踪链接，默认使用17 track
            number = orderEntity.getWayBillNumber();
            logisticUrl = LOGISTICS_TRACKING_URL.replace(TRACK_NUMBER, number);
        } else {
            TransportTypeEnum transportType = thirdPartyLogisticsUrlEntity.getTransportType();
            if (TransportTypeEnum.WHOLE_JOURNEY.equals(transportType)) {
                number = orderEntity.getWayBillNumber();
                logisticUrl = thirdPartyLogisticsUrlEntity.getQueryUrl().replace(TRACK_NUMBER, number);
            } else {
                GetTrackingNumberRequest getTrackingNumberRequest = new GetTrackingNumberRequest();
                getTrackingNumberRequest.setCustomerOrderNumber(orderEntity.getSysOrderId());

                GetTrackingNumberResponse trackingNumberResponse = omsYunExpressApiService.getTrackingNumber(getTrackingNumberRequest);
                number = (trackingNumberResponse.success() && StringUtils.isNotBlank(trackingNumberResponse.getItems().get(0).getTrackingNumber()))
                        ? trackingNumberResponse.getItems().get(0).getTrackingNumber()
                        : orderEntity.getWayBillNumber();
                logisticUrl = thirdPartyLogisticsUrlEntity.getQueryUrl().replace(TRACK_NUMBER, number);
            }
        }
        trackingInfo.setNumber(number);
        trackingInfo.setUrl(logisticUrl);
    }
}
